<template>
  <!-- class list-adding 控制列表是否添加新卡片的状态 -->
  <div
    class="list-wrap"
    :class="{ 'list-adding': listAdding }"
    :data-order="data.order"
  >
    <div class="list-placeholder" ref="listPlaceHolder"></div>

    <div class="list" ref="list">
      <!-- 列表标题 -->
      <div class="list-header" ref="listHeader">
        <textarea
          class="form-field-input"
          ref="newListName"
          @mousedown.prevent
          @blur="editListName"
          v-model="data.name"
        ></textarea>
        <div class="extras-menu">
          <span class="icon icon-more"></span>
        </div>
      </div>

      <div class="list-cards">
        <!-- 卡片正文 -->
        <Card v-for="card of cards" :key="card.id" :data="card"></Card>

        <div class="list-card-add-form">
          <textarea
            ref="newCardName"
            class="form-field-input"
            placeholder="为这张卡片添加标题……"
          ></textarea>
        </div>
      </div>

      <div class="list-footer">
        <div class="list-card-add" @click="showAddCard">
          <span class="icon icon-add"></span>
          <span>添加另一张卡片</span>
        </div>
        <div class="list-add-confirm">
          <button class="btn btn-success" @click="addNewCard">添加卡片</button>
          <span class="icon icon-close" @click="hideAddCard"></span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Card from "@/components/Card/card";

export default {
  name: "List",
  components: { Card },
  props: {
    data: {
      type: Object,
    },
  },

  data() {
    return {
      drag: {
        isMouseDown: false,
        isDrag: false,
        mouseDownClientX: 0,
        mouseDownClientY: 0,
        mouseDownElementX: 0,
        mouseDownElementY: 0,
      },

      listAdding: false,
    };
  },

  computed: {
    cards() {
      return this.$store.getters["card/getterCards"](this.data.id);
    },
  },

  async created() {
    if (!this.cards.length) {
      await this.$store.dispatch("card/getCards", this.data.id);
    }
  },

  mounted() {
    this.$refs.listHeader.addEventListener("mousedown", this.dragDown);
    document.addEventListener("mousemove", this.dragMove);
    document.addEventListener("mouseup", this.dragUp);
  },

  methods: {
    //  显示添加卡片的输入表单
    showAddCard() {
      this.listAdding = true;

      this.$nextTick(() => {
        this.$refs.newCardName.focus();
      });
    },

    //  关闭添加卡片的输入表单
    hideAddCard() {
      this.listAdding = false;
      this.$refs.newCardName.value = "";
    },

    //  添加新卡片
    addNewCard() {
      let value = this.$refs.newCardName.value;

      if (value.trim() !== "") {
        try {
          this.$store.dispatch("card/postCard", {
            boardListId: this.data.id,
            name: value,
          });
          this.$refs.newCardName.value = "";
          this.$message.success("添加成功");
        } catch (error) {
          console.log(error);
        }
      } else {
        this.$refs.newCardName.focus();
      }
    },

    //  编辑列表的名称
    async editListName() {
      await this.$store.dispatch("list/editList", {
        boardId: this.data.boardId,
        id: this.data.id,
        name: this.data.name,
      });
    },

    dragDown(e) {
      //  获取鼠标按下时，鼠标的坐标
      this.drag.isMouseDown = true;
      this.drag.mouseDownClientX = e.clientX;
      this.drag.mouseDownClientY = e.clientY;

      //  获取鼠标按下时，标题所在的坐标离屏幕左上角的距离
      let { x, y } = this.$refs.list.getBoundingClientRect();
      this.drag.mouseDownElementX = x;
      this.drag.mouseDownElementY = y;
    },

    dragMove(e) {
      //  检测是否有拖拽的动作
      if (this.drag.isMouseDown) {
        let listEle = this.$refs.list;

        //  获取移动鼠标移动元素的距离
        let deltaX = e.clientX - this.drag.mouseDownElementX;
        let deltaY = e.clientY - this.drag.mouseDownElementY;

        //  满足触发拖拽的条件
        if (deltaX > 10 || deltaY > 10) {
          //  此时处于dragstart状态
          if (!this.drag.isDrag) {
            this.drag.isDrag = true;

            //  设置list在原来位置的阴影
            this.$refs.listPlaceHolder.style.height =
              listEle.offsetHeight + "px";

            //  处于dragstart时，让元素变成绝对定位状态
            listEle.style.position = "absolute";
            listEle.style.zIndex = 999;
            listEle.style.transform = "rotate(5deg)";
            document.body.appendChild(listEle);

            this.$emit("dragStart", {
              component: this,
            });
          }

          //  此时处于drag状态
          listEle.style.left = this.drag.mouseDownElementX + deltaX + "px";
          listEle.style.top = this.drag.mouseDownElementY + deltaY + "px";

          //  将事件丢去外部进行处理，实现列表的拖拽交换
          this.$emit("dragMove", {
            component: this,
            x: e.clientX,
            y: e.clientY,
          });
        }
      }
    },

    dragUp(e) {
      //  是否点击过
      if (this.drag.isMouseDown) {
        if (this.drag.isDrag) {
          //  处于dragend状态
          let listEle = this.$refs.list;
          listEle.style.position = "relative";
          listEle.style.zIndex = 0;
          listEle.style.left = 0;
          listEle.style.top = 0;
          listEle.style.transform = "rotate(0deg)";
          this.$el.appendChild(listEle);

          this.$refs.listPlaceHolder.style.height = 0;
          this.$emit("dragEnd", {
            component: this,
          });
        } else {
          // 并非拖拽，单纯的点击
          if (e.path.includes(this.$refs.newListName)) {
            //  在上面阻止了input的mousedown的默认行为，这里给他手动调用
            this.$refs.newListName.select();
          }
        }
      }

      this.drag.isMouseDown = false;
      this.drag.isDrag = false;
    },
  },
};
</script>

<style>
</style>